package org.spring.config.client.listener;

import java.lang.reflect.Method;

import javax.annotation.Resource;

import org.spring.config.client.groovy.Foo;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

@Component
@EnableScheduling
public class ConfigJob {
    // @Resource
    // private Foo foo;

    @Resource
    private ConfigurableApplicationContext context;

    @Scheduled(cron = "00/60 * * * * ?")
    public void send() {
        // foo.execute();

//        Foo foo = context.getBean(Foo.class);
//        foo.execute();
//        System.out.println(context.getBean(Foo.class));

        String message = "Hello World---" + System.currentTimeMillis();
//        try {
//            
//            registerController("scriptFactory.TestController");
//
////            registerController("org.spring.config.client.groovy.TestController");
//        } catch (Exception e) {
//            
//            		// TODO Auto-generated catch block
//            		e.printStackTrace();
//            	
//        }

    }
    
    
    /**
     * 去掉Controller的Mapping
     * 
     * @param controllerBeanName
     */
    public void unregisterController(String controllerBeanName) {
        final RequestMappingHandlerMapping requestMappingHandlerMapping =
            (RequestMappingHandlerMapping)context.getBean("requestMappingHandlerMapping");
        if (requestMappingHandlerMapping != null) {
            String handler = controllerBeanName;
            Object controller = context.getBean(handler);
            if (controller == null) {
                return;
            }
            final Class<?> targetClass = controller.getClass();
            ReflectionUtils.doWithMethods(targetClass, new ReflectionUtils.MethodCallback() {
                public void doWith(Method method) {
                    Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
                    try {
                        Method createMappingMethod = RequestMappingHandlerMapping.class
                            .getDeclaredMethod("getMappingForMethod", Method.class, Class.class);
                        createMappingMethod.setAccessible(true);
                        RequestMappingInfo requestMappingInfo = (RequestMappingInfo)createMappingMethod
                            .invoke(requestMappingHandlerMapping, specificMethod, targetClass);
                        if (requestMappingInfo != null) {
                            requestMappingHandlerMapping.unregisterMapping(requestMappingInfo);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }, ReflectionUtils.USER_DECLARED_METHODS);
        }
    }

    /**
     * 注册Controller
     * 
     * @param controllerBeanName
     * @throws Exception
     */
    public void registerController(String controllerBeanName) throws Exception {

        final RequestMappingHandlerMapping requestMappingHandlerMapping =
            (RequestMappingHandlerMapping)context.getBean("requestMappingHandlerMapping");

        if (requestMappingHandlerMapping != null) {

            String handler = controllerBeanName;
            Object controller = context.getBean(handler);
            if (controller == null) {
                return;
            }
            unregisterController(controllerBeanName);
            // 注册Controller
            Method method = requestMappingHandlerMapping.getClass().getSuperclass().getSuperclass()
                .getDeclaredMethod("detectHandlerMethods", Object.class);
            method.setAccessible(true);
            method.invoke(requestMappingHandlerMapping, handler);
        }
    }
}
